import pandas as pd
from pyecharts.charts import Page, Kline, Bar, Grid, Line
from pyecharts import options as opts
import webbrowser as wb

csv_file_name = '南玻A.csv'

stock_data = pd.read_csv(csv_file_name, encoding='gb2312')#文件读取
stock_data = stock_data.sort_values(by=["日期"], ascending=[True], inplace=False)#
stock_data_cleared = stock_data[stock_data['收盘价'] > 0]#数据清洗
stock_name = stock_data_cleared["名称"][0]
row_count = stock_data_cleared.shape[0]
stock_data_extracted = stock_data_cleared[["开盘价", "收盘价", "最低价", "最高价", "成交量", "日期"]]

# 移动平均数计算
def moving_average(data, day_count):
    data = data.values[:, 0]
    result = []
    for i in range(len(data)):
        start_day_index = i - day_count + 1
        if start_day_index <= 0:
            start_day_index = 0
        justified_day_count = i - start_day_index + 1
        mean = data[start_day_index:i + 1].sum() / justified_day_count
        result.append(mean)
    return result

# k线
kline = (
    Kline(init_opts=opts.InitOpts(bg_color='rgba(255,250,205,0.2)',width="1600px",height="800px"))
        .add_xaxis(stock_data_extracted["日期"].values.tolist())
        .add_yaxis("K线图", stock_data_extracted.iloc[:, :4].values.tolist())
        .set_global_opts(
        xaxis_opts=opts.AxisOpts(is_scale=True, is_show=False),
        # axis_opts=opts.AxisOpts(is_scale=True,min_=0), #y轴起始坐标可以设为0
        yaxis_opts=opts.AxisOpts(is_scale=True),  # y轴起始坐标可自动调整
        title_opts=opts.TitleOpts(title="价格", subtitle=stock_name + "\n" , pos_top="20%"),
        axispointer_opts=opts.AxisPointerOpts(
            is_show=True,
            link=[{"xAxisIndex": "all"}],
            label=opts.LabelOpts(background_color="#777"),
        ),
        datazoom_opts=[  # 设置zoom参数后即可缩放
            opts.DataZoomOpts(
                is_show=True,
                type_="inside",
                xaxis_index=[0, 1],  # 设置第0轴和第1轴同时缩放
                range_start=0,
                range_end=100,
            ),
            opts.DataZoomOpts(
                is_show=True,
                xaxis_index=[0, 1],
                type_="slider",
                pos_top="90%",
                range_start=0,
                range_end=100,
            ),
        ],

    )
)

# 移动平均线
line = (
    Line(init_opts=opts.InitOpts(bg_color='rgba(255,250,205,0.2)',
        width='2000px',
        height='1200px'))
        .add_xaxis(xaxis_data=stock_data_extracted["日期"].values.tolist())
        .add_yaxis(
        series_name="MA5",
        y_axis=moving_average(stock_data_extracted[["收盘价"]], 5),
        is_smooth=True,
        is_hover_animation=False,
        linestyle_opts=opts.LineStyleOpts(width=1, opacity=0.5),
        label_opts=opts.LabelOpts(is_show=False),
    )
        .add_yaxis(
        series_name="MA10",
        y_axis=moving_average(stock_data_extracted[["收盘价"]], 10),
        is_smooth=True,
        is_hover_animation=False,
        linestyle_opts=opts.LineStyleOpts(width=1, opacity=0.5),
        label_opts=opts.LabelOpts(is_show=False),
    )
        .add_yaxis(
        series_name="MA30",
        y_axis=moving_average(stock_data_extracted[["收盘价"]], 30),
        is_smooth=True,
        is_hover_animation=False,
        linestyle_opts=opts.LineStyleOpts(width=1, opacity=0.5),
        label_opts=opts.LabelOpts(is_show=False),
    )
        .set_global_opts(xaxis_opts=opts.AxisOpts(type_="category"))
)

# 将K线图和移动平均线显示在一个图内
kline.overlap(line)

# 成交量柱形图
x = stock_data_extracted[["日期"]].values[:, 0].tolist()
y = stock_data_extracted[["成交量"]].values[:, 0].tolist()

bar = (
    Bar(init_opts=opts.InitOpts(bg_color='rgba(255,250,205,0.2)',
        width="2000px",
        height="1200px"))
        .add_xaxis(x)
        .add_yaxis("成交量", y, label_opts=opts.LabelOpts(is_show=False),
                   itemstyle_opts=opts.ItemStyleOpts(color="#008080"))
        .set_global_opts(title_opts=opts.TitleOpts(title="成交量", pos_top="70%"),
                         legend_opts=opts.LegendOpts(is_show=False),
                         )
)

# 使用网格将多张图标组合到一起显示
gird_chart = Grid(init_opts=opts.InitOpts(bg_color='rgba(255,250,205,0.2)',width="2000px",height="1200px"))
grid_chart = Grid()

grid_chart.add(
    kline,
    grid_opts=opts.GridOpts(pos_left="15%", pos_right="8%", height="55%"),
)

grid_chart.add(
    bar,
    grid_opts=opts.GridOpts(pos_left="15%", pos_right="8%", pos_top="70%", height="20%"),
)

grid_chart.render("kline_test.html")
wb.open("kline_test.html")